<?php

namespace app\admin\controller\wms;

use think\Request;
use Throwable;
use app\admin\model\Admin;
use app\common\controller\Backend;
use app\admin\model\wms\Exts;
use \app\admin\model\wms\Skus;
use think\db\exception\PDOException;
use think\exception\ValidateException;
use think\facade\Db;
use Exception;

/**
 * 兼容之前系统商品
 */
class Products extends Backend
{
     /**
      * Products模型对象
      * @var object
      * @phpstan-var \app\admin\model\wms\Products
      */
     protected object $model;

     protected array|string $preExcludeFields = ['id'];

     protected string|array $quickSearchField = ['id'];

     public function initialize(): void
     {
          parent::initialize();
          $this->model = new \app\admin\model\wms\Products;
     }


     /**
      * 若需重写查看、编辑、删除等方法，请复制 @see \app\admin\library\traits\Backend 中对应的方法至此进行重写
      */


     public function index(): void
     {
          if ($this->request->param('select')) {
               $this->select();
          }

          list($where, $alias, $limit) = $this->queryBuilder();
          $requestParams = $this->params;
//          $validKeys = ['status', 'category3_id', 'brand_id', 'ean'];
//          $where = array_filter($requestParams, function ($value, $key) use ($validKeys) {
//              return in_array($key, $validKeys);
//          }, ARRAY_FILTER_USE_BOTH);
         // 查询的字段
          $field = 'id,title,ean,money_price,status,created_at,thumb,stock,admin_id,category_ids,category_names,list_weight,rarity';
          $query = $this->model
               ->field($field)
               ->withSearch(['title','ean','category','status'],$requestParams)
               ->withJoin($this->withJoinTable, $this->withJoinType)
               ->where($where);

          if (isset($requestParams['money_price_min'])) {
               $query->where('money_price', '>', intval($requestParams['money_price_min']) * 100);
          }
          if (isset($requestParams['money_price_max'])) {
               $query->where('money_price', '<', intval($requestParams['money_price_max']) * 100);
          }
          if (isset($requestParams['title'])) {
               $query->where('title', 'like', '%' . $requestParams['title'] . '%');
          }
          //排序
          $order = ['list_weight' => 'desc'];
          if (isset($requestParams['order_by'])) {
               $order = match ($requestParams['order_by']) {
                    '1' => ['money_price' => 'desc'],
                    '2' => ['money_price' => 'asc'],
                    '3' => ['created_at' => 'desc'],
                    '4' => ['created_at' => 'asc'],
                    default => ['list_weight' => 'desc'],
               };

          }
          //然后查询的时候限定ID 只能在这个范围里
//          if (isset($requestParams['stock'])) {
//               // 获取已售罄商品
//               $soldOutProducts = $this->model->with('skus')->select()->filter(function ($product) {
//                    $totalStock = array_sum(array_column($product->skus->toArray(), 'stock'));
//                    return $totalStock <= 0;
//               });
//               $soldOutTotal = count($soldOutProducts); // 使用新的售罄总数
//               $query->where('id', 'in', array_column($soldOutProducts->toArray(), 'id'));
//          }

          $res = $query->with(['admin'])->order($order)->paginate($limit);
//          $onShelfTotal = $this->model->where(['status' => 1, 'is_del' => 1])->count();
            $onShelfTotal = $this->model->where(['status' => 1])->count();
//          $offShelfTotal = $this->model->where(['status' => 0, 'is_del' => 1])->count();
            $offShelfTotal = $this->model->where(['status' => 0,])->count();
//          foreach ($res as &$value) {
//               $value['money_price'] = $value['money_price'] ? intval($value['money_price']) / 100 : 0;
//               $value['stock'] = array_sum(array_column($value->skus->toArray(), 'stock'));
//               foreach ($value['skus'] as &$vv) {
//                    $vv['product_spec'] = $vv['product_spec'] ? : [];
//               }
//          }
          $this->success('', [
               'list' => $res->items(),
               'total' => $res->total(),
               'on_shelf_total' => $onShelfTotal,
               'off_shelf_total' => $offShelfTotal,
//               'sold_out_total' => $soldOutTotal ?? 0,
          ]);
     }



     //商品详情
     public function detail(): void
     {
          $id = $this->request->get('id');
          $field = 'id,title,ean,money_price,status,created_at,thumb,stock,admin_id,category_ids,category_names,sub_title,tags,rarity,list_weight,stock';
          $res = $this->model->field($field)->where('id', $id)->find();
          if(!$res){
               $this->error('商品不存在');
          }

          $res['skus'] = Skus::where('product_id', $id)->field('id,product_spec,money_price')->select();
          $res['tags'] = ($res['tags'] == "[]") ? null : $res['tags'];
          $this->success('', $res);
     }


     /**
      * 添加
      */
     public function add(): void
     {
          if ($this->request->isPost()) {

               $data = $this->request->post();

               if (!$data) {
                    $this->error(__('Parameter %s can not be empty', ['']));
               }
//               //过滤字段
//               $data = $this->excludeFields($data);
//               if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
//                    $data[$this->dataLimitField] = $this->auth->id;
//               }
               $result = false;
               $this->model->startTrans();
               try {
                    // 模型验证--数据是否正确 先关闭
//                    if ($this->modelValidate) {
//                         $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
//                         if (class_exists($validate)) {
//                              $validate = new $validate;
//                              if ($this->modelSceneValidate) $validate->scene('add');
//                              $validate->check($data);
//                         }
//                    }
                   $categoryIdArr = explode(",",$data['category_ids']);

                   $skuInfos = $data['skus']??[];
                    $productInfo = [
                         'title' => $data['title'],
                         'sub_title' => $data['sub_title'],
                         'uuid' => uniqid(),
                         'search_key' => $data['search_key'] ?? '',
                         'thumb' => $data['thumb'],
                         'number' => $data['number'] ?? '',
                         'ean' => $data['ean'],
                         'rarity' => $data['rarity'],
                         'money_price' =>  $skuInfos[0]['money_price']??0,
                         'line_money_price' => $data['line_money_price'] ?? '',
                         'score_price' => $data['score_price'] ?? '',
                         'magic_point_price' => $data['magic_point_price'] ?? '',
                         'category_ids' => $data['category_ids'] ?? '',
                         'brand_id' => $data['brand_id'] ?? '',
                         'status' => $data['status'] ?? '',
                         'tags' => $data['tags'] ?? '',
                         'is_need_address' => $data['is_need_address'] ?? '',
                         'is_free_carriage' => $data['is_free_carriage'] ?? '',
                         'carriage_type' => $data['carriage_type'] ?? '',
                         'carriage' => $data['carriage'] ?? '',
                         'is_offline_useable' => $data['is_offline_useable'] ?? '',
                         'is_presell' => $data['is_presell'] ?? '',
                         'presell_mode' => $data['presell_mode'] ?? '',
                         'published_at' => date('Y-m-d H:i:s', time()),
                         'created_at' => date('Y-m-d H:i:s', time()),
                         'remark' => $data['remark'] ?? '',
                         'admin_id' => $this->auth->id,
                         'warehouse_shelf_id' => $data['warehouse_shelf_id'] ?? '',
                         'category1_id' => $categoryIdArr[0]??null,
                         'category2_id' => $categoryIdArr[1]??null,
                         'category3_id' => $categoryIdArr[2]??null,
                         'stock' => $data['stock'] ?? 0,
                         'list_weight' => $data['list_weight'] ?? 0,
                    ];
                    if (!empty($data['presell_date'])) {
                         $productInfo['presell_date'] = $data['presell_date'];
                    }
//                    //新增商品
                    $result = $this->model->create($productInfo);
//                   //新增商品拓展信息
//                    $extInfo['product_id'] = $result->id;
//                    $attrs = html_entity_decode($data['sku_attrs'], ENT_QUOTES, 'UTF-8');
//                    $image_json = json_encode(explode(',', $data['images']));
//                    $extInfo = [
//                         'uuid' => uniqid(),
//                         'images' => $image_json,
//                         'normal_attrs' => $data['normal_attrs'] ?? [],
//                         'sku_attrs' => $attrs ?? [],
//                         'page' => $data['page'] ?? [],
//                         'product_id' => $result->id,
//                         'created_at' => date('Y-m-d H:i:s', time()),
//                    ];
//                    Exts::create($extInfo);
                    //新增商品sku信息



                    $array = [];

                    foreach ($skuInfos as $key => $sku) {
                         $array[$key]['uuid'] = uniqid();
                         $array[$key]['product_id'] = $result->id;
                         $array[$key]['number'] = $sku['number'] ?? '';
                         $array[$key]['sku_title'] = $sku['sku_title'] ?? $sku['product_spec'];
                         $array[$key]['thumb'] = $sku['thumb']['0'] ?? '';
                         $array[$key]['money_price'] = $sku['money_price'] ?? 0;
                         $array[$key]['product_spec'] = explode(',',$sku['product_spec']) ?? '';
                         $array[$key]['magic_point_price'] = $sku['magicPrice']??'';
                         $array[$key]['score_price'] = $sku['scorePrice']??'';
                         $array[$key]['attrs'] = $attrs ?? [];
                         $array[$key]['stock'] = $sku['stock'] ?? 0;
                         $array[$key]['status'] = $sku['isOnline'] ??1;
                         $array[$key]['created_at'] = date('Y-m-d H:i:s', time());
                    }

                    //批量插入
                    Skus::insertAll($array);
                    $this->model->commit();
               } catch (Throwable $e) {
                    $this->model->rollback();
                    $this->error($e->getMessage());
               }
               if ($result !== false) {
                    $this->success(__('Added successfully'));
               } else {
                    $this->error(__('No rows were added'));
               }
          }

          $this->error(__('Parameter error'));
     }

     /**
      * 编辑
      * @throws Throwable
      */
     public function edit(): void
     {
          $pk = $this->model->getPk();
          $id = $this->request->param($pk);
          $row = $this->model->find($id);
          if (!$row) {
               $this->error(__('Record not found'));
          }


//          $dataLimitAdminIds = $this->getDataLimitAdminIds();
//          if ($dataLimitAdminIds && !in_array($row[$this->dataLimitField], $dataLimitAdminIds)) {
//               $this->error(__('You have no permission'));
//          }

          if ($this->request->isPost()) {
               $data = $this->request->post();

               if (!$data) {
                    $this->error(__('Parameter %s can not be empty', ['']));
               }
               //$jsonStringDecoded = html_entity_decode($data['skus'], ENT_QUOTES, 'UTF-8');
//               $data = $this->excludeFields($data);
               $result = false;
               $this->model->startTrans();
              $categoryIdArr = explode(",",$data['category_ids']);
              $skuInfos = $data['skus']??[];
               try {

//                    // 模型验证
//                    if ($this->modelValidate) {
//                         $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
//                         if (class_exists($validate)) {
//                              $validate = new $validate;
//                              if ($this->modelSceneValidate) $validate->scene('edit');
//                              $data[$pk] = $row[$pk];
//                              $validate->check($data);
//                         }
//                    }
                    $productInfo = [
                         'title' => $data['title'],
                         'search_key' => $data['search_key'] ?? '',
                         'thumb' => $data['thumb'],
                         'number' => $data['number'] ?? '',
                         'ean' => $data['ean'],
                         'money_price' => $skuInfos[0]['money_price']??0,
                         'line_money_price' => $data['line_money_price'] ?? '',
                         'score_price' => $data['score_price'] ?? '',
                         'magic_point_price' => $data['magic_point_price'] ?? '',
                         'category_ids' => $data['category_ids'] ?? '',
                         'brand_id' => $data['brand_id'] ?? '',
                         'status' => $data['status'] ?? '',
                         'tags' => $data['tags'] ?? '',
                         'is_need_address' => $data['is_need_address'] ?? '',
                         'is_free_carriage' => $data['is_free_carriage'] ?? '',
                         'carriage_type' => $data['carriage_type'] ?? '',
                         'carriage' => $data['carriage'] ?? '',
                         'is_offline_useable' => $data['is_offline_useable'] ?? '',
                         'is_presell' => $data['is_presell'] ?? '',
                         'presell_mode' => $data['presell_mode'] ?? '',
                         'presell_date' => $data['presell_date'] ?? date('Y-m-d H:i:s', time()),
                         'remark' => $data['remark'] ?? '',
                         'admin_id' => $this->auth->id,
                         'warehouse_shelf_id' => $data['warehouse_shelf_id'] ?? '',
                         'category1_id' => $categoryIdArr[0]??null,
                         'category2_id' => $categoryIdArr[1]??null,
                         'category3_id' => $categoryIdArr[2]??null,
                         'stock' => $data['stock'] ?? 0,
                         'rarity' => $data['rarity'] ??'',
                         'list_weight' => $data['list_weight'] ?? 0,
                    ];
//                    //新增商品
                    $result = $this->model->where(['id' => $id])->update($productInfo);
//                    //新增商品拓展信息
//                    $attrs = html_entity_decode($data['sku_attrs'], ENT_QUOTES, 'UTF-8');
//                    $image_json = json_encode(explode(',', $data['images']));
//                    $extInfo = [
//                         'images' => $image_json,
//                         'normal_attrs' => $data['normal_attrs'] ?? [],
//                         'sku_attrs' => $attrs ?? [],
//                         'page' => $data['page'] ?? [],
//                         'updated_at' => date('Y-m-d H:i:s', time()),
//                    ];
//                    Exts::where(['product_id' => $id])->update($extInfo);
                    //新增商品sku信息

                    $array = [];
                    //查询一下是否有已经生成过的uuid
                    $sku_uuid = Skus::where(['product_id' => $id])->column('sku_title');
                    $sku_info_uuid = array_column($skuInfos, 'product_spec');
                    //取出上面两个的差集
                    $diff = array_diff($sku_uuid, $sku_info_uuid);
                    //如果有差集 说明有删除的sku
                    if (!empty($diff)) {
                         Skus::where(['product_id' => $id])->where('sku_title', 'in', $diff)->delete();
                    }
                    foreach ($skuInfos as $key => $sku) {
                         $array['number'] = $sku['number'] ?? '';
                         $array['thumb'] = $sku['thumb']['0'] ?? '';
                         $array['sku_title'] = $sku['product_spec'];
                         $array['money_price'] = $sku['money_price'] ?? 0;
                         $array['product_spec'] = explode(',',$sku['product_spec']) ?? '';
                         $array['magic_point_price'] = $sku['magicPrice']??'';
                         $array['score_price'] = $sku['scorePrice']??'';
                         $array['attrs'] = $attrs ?? [];
                         $array['stock'] = $sku['stock'] ?? 0;
                         $array['status'] = $sku['isOnline'] ??1;
                         // 检查SKU规格是否已存在
                         if ($skuId = Skus::where('sku_title',$array['sku_title'])->where('product_id',$id)->column('id')) {
                              // 如果SKU有UUID，我们需要更新这个SKU
                              // 首先，我们设置更新时间为当前时间
                              $array['updated_at'] = date('Y-m-d H:i:s', time());
                              // 然后，我们在数据库中找到UUID匹配的SKU，并使用$array中的新数据进行更新
                              Skus::where(['id' => $skuId])->update($array);
                         } else {
                              // 如果SKU没有UUID，我们需要创建一个新的SKU
                              // 首先，我们生成一个新的UUID
                              $array['uuid'] = uniqid();
                              // 然后，我们设置新SKU的商品ID
                              $array['product_id'] = $id;
                              // 接着，我们设置创建时间为当前时间
                              $array['created_at'] = date('Y-m-d H:i:s', time());
                              // 最后，我们在数据库中插入新的SKU，$array中包含了新SKU的数据
                              Skus::create($array);
                         }
                    }

                    $this->model->commit();
               } catch (Throwable $e) {
                    $this->model->rollback();
                    $this->error($e->getMessage());
               }
               if ($result !== false) {
                    $this->success(__('Update successful'));
               } else {
                    $this->error(__('No rows updated'));
               }
          }
     }


     //修改商品上下架
     public function changeStatus(): void
     {
          $id = $this->request->post('id');
          $status = $this->request->post('status');
          $res = $this->model->where('id', $id)->update(['status' => $status]);
          if ($res) {
               $this->success('操作成功');
          } else {
               $this->error('操作失败');
          }
     }

     //同步商品到其他数据库
     public function syncProduct(): void
     {
          $id = $this->request->post('ids');
          //获取所有商品信息
          $ids = explode(',', $id);
          $res = $this->model->where('id', 'in', $ids)->select()->toArray();
          $data = [];
          foreach ($res as $value) {
               $data[] = [
                    'id' => $value['id'],
                    'product_no' => $value['product_no'],
                    'product_name' => $value['product_name'],
                    'product_image' => $value['product_image'],
                    'product_price' => $value['product_price'],
                    'product_stock' => $value['stock'],
                    'product_status' => $value['status'],
                    'product_create_time' => $value['create_time'],
                    'product_update_time' => $value['update_time'],
               ];
          }
          $res = Db::connect('mysql1')->name('products')->insertAll($data);
          if ($res) {
               $this->success('同步成功');
          } else {
               $this->error('同步失败');
          }
     }

     //修改商品排序
     public function changeSort(): void
     {
          $id = $this->request->post('id');
          $sort = $this->request->post('list_weight');
          $res = $this->model->where('id', $id)->update(['list_weight' => $sort]);
          if ($res) {
               $this->success('操作成功');
          } else {
               $this->error('操作失败');
          }
     }

     //修改商品标题
     public function changeTitle(): void
     {
          $id = $this->request->post('id');
          $title = $this->request->post('title');
          $category_ids = $this->request->post('category_ids');
          $ean = $this->request->post('ean');
          $remark = $this->request->post('remark');
          $res = $this->model->where('id', $id)->update([
               'title' => $title,
               'category_ids' => $category_ids,
               'remark' => $remark,
               'ean' => $ean
          ]);
          if ($res) {
               $this->success('操作成功');
          } else {
               $this->error('操作失败');
          }
     }

     //商品库存盘点功能  并且覆盖之前库存 接收参数 商品ID 商品库存 商品备注

     public function stockInquiry(): void
     {
          $data = $this->request->post('data');
          $arr = json_decode($data);
          foreach ($arr as $value) {
               $res = $this->model->where('id', $value['id'])->update(['stock' => $value['stock']]);
               // 同时在库存盘点表插入一条库存变更记录
               $data = [
                    'product_id' => $value['id'],
                    'stock' => $value['stock'],
                    'remark' => $value['remark'],
                    'admin_id' => $this->auth->id,
               ];
               \app\admin\model\wms\Stocks::create($data);
          }
          if ($res) {
               $this->success('操作成功');
          } else {
               $this->error('操作失败');
          }
     }

     //修改商品数量
     public function changeStock(): void
     {
          $id = $this->request->post('id');
          $stock = $this->request->post('stock');
          $res = $this->model->where('id', $id)->update(['stock' => $stock]);
          if ($res) {
               $this->success('操作成功');
          } else {
               $this->error('操作失败');
          }
     }


     /**
      * 删除
      * @param array $ids
      * @throws Throwable
      */
     public function del(array $ids = []): void
     {

          if (!$this->request->isDelete() || !$ids) {
               $this->error(__('Parameter error'));
          }

          $where = [];
          $dataLimitAdminIds = $this->getDataLimitAdminIds();
          if ($dataLimitAdminIds) {
               $where[] = [$this->dataLimitField, 'in', $dataLimitAdminIds];
          }
          $pk = $this->model->getPk();
          $where[] = [$pk, 'in', $ids];

          $count = 0;
          $data = $this->model->where($where)->select();
          $this->model->startTrans();
          try {
               foreach ($data as $v) {
                   $count += $v->delete();
               }
               $this->model->commit();
          } catch (Throwable $e) {
               $this->model->rollback();
               $this->error($e->getMessage());
          }
          if ($count) {
               $this->success(__('Deleted successfully'));
          } else {
               $this->error(__('No rows were deleted'));
          }
     }

     //回收站
     public function recycle(): void
     {
          if ($this->request->param('select')) {
               $this->select();
          }

          list($where, $alias, $limit) = $this->queryBuilder();
          $requestParams = $this->request->param();
          $validKeys = ['status', 'category1_id', 'brand_id', 'ean'];
          $where = array_filter($requestParams, function ($value, $key) use ($validKeys) {
               return in_array($key, $validKeys);
          }, ARRAY_FILTER_USE_BOTH);
          $where['is_del'] = 2;
          $query = $this->model
               ->field($this->indexField)
               ->withJoin($this->withJoinTable, $this->withJoinType)
               ->where($where);

          if (isset($requestParams['money_price_min'])) {
               $query->where('money_price', '>', $requestParams['money_price_min'] * 100);
          }
          if (isset($requestParams['money_price_max'])) {
               $query->where('money_price', '<', $requestParams['money_price_max'] * 100);
          }
          if (isset($requestParams['title'])) {
               $query->where('title', 'like', '%' . $requestParams['title'] . '%');
          }
          //排序
          $order = ['list_weight' => 'desc'];
          if (isset($requestParams['order_by'])) {
               $order = match ($requestParams['order_by']) {
                    '1' => ['money_price' => 'desc'],
                    '2' => ['money_price' => 'asc'],
                    '3' => ['created_at' => 'desc'],
                    '4' => ['created_at' => 'asc'],
                    default => ['list_weight' => 'desc'],
               };

          }
          //然后查询的时候限定ID 只能在这个范围里
          if (isset($requestParams['stock'])) {
               // 获取已售罄商品
               $soldOutProducts = $this->model->with('skus')->select()->filter(function ($product) {
                    $totalStock = array_sum(array_column($product->skus->toArray(), 'stock'));
                    return $totalStock <= 0;
               });
               $soldOutTotal = count($soldOutProducts); // 使用新的售罄总数
               $query->where('id', 'in', array_column($soldOutProducts->toArray(), 'id'));
          }
          $res = $query->with('skus')->order($order)->paginate($limit);
          $onShelfTotal = $this->model->where(['status' => 1, 'is_del' => 1])->count();
          $offShelfTotal = $this->model->where(['status' => 0, 'is_del' => 1])->count();
          foreach ($res as &$value) {
               $value['responsible_person_text'] = $value->admin->nickname ?? '--';
               $value['money_price'] = $value['money_price'] ? $value['money_price'] / 100 : 0;
               $value['stock'] = array_sum(array_column($value->skus->toArray(), 'stock'));
               foreach ($value['skus'] as &$vv) {
                    $vv['product_spec'] = $vv['product_spec'] ? json_decode($vv['product_spec'], true) : [];
               }
          }
          $this->success('', [
               'list' => $res->items(),
               'total' => $res->total(),
               'on_shelf_total' => $onShelfTotal,
               'off_shelf_total' => $offShelfTotal,
               'sold_out_total' => $soldOutTotal ?? 0,
          ]);
     }

     //恢复已经删除的商品
     public function recover(): void
     {
          $id = $this->request->post('id');
          $res = $this->model->where('id', $id)->update(['is_del' => 1]);
          if ($res) {
               $this->success('操作成功');
          } else {
               $this->error('操作失败');
          }
     }
}
